﻿using Kingdee.BOS;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Core.Metadata.ControlElement;
using Kingdee.BOS.Core.Metadata.ElementMetadata;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.Util;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Orm.Metadata.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Kingdee.BOS.Orm.DataEntity;

namespace RK.FormPlugin.BPW
{
    [Description("动态表单，动态创建列并绑定数据,审核专员审核销售订单"), HotUpdate]
    public class SalOrderToAudit : AbstractDynamicFormPlugIn
    {
        #region var
        /// <summary>
        /// 单据体标识
        /// </summary>
        private const string entityKey = "F_POSW_Entity_qtr";
        /// <summary>
        /// 需要动态创建的列的列名
        /// </summary>
        private string[] fieldNames = new string[] { "编码", "名称", "备注" };
        /// <summary>
        /// 动态表格的布局元数据
        /// </summary>
        private LayoutInfo dynamicLayoutInfo = new LayoutInfo("F_Jac_Layout");
        #endregion
        #region event
        /// <summary>
        /// 初始化动态表格的布局元数据
        /// </summary>
        /// <param name="e"></param>
        public override void OnInitializeService(InitializeServiceEventArgs e)
        {
            base.OnInitializeService(e);
            MetadataUtils.CreateFields(this.Context, dynamicLayoutInfo, entityKey, fieldNames);
        }
        /// <summary>
        /// 动态设置表单业务元数据
        /// </summary>
        /// <param name="e"></param>
        public override void OnSetBusinessInfo(SetBusinessInfoArgs e)
        {
            base.OnSetBusinessInfo(e);
            // 动态创建businessinfo，先移除后添加
            var businessInfo = (BusinessInfo)ObjectUtils.CreateCopy(this.View.BusinessInfo);
            var entityFields = businessInfo.GetFieldList().Where(o => o.EntityKey.EqualsIgnoreCase(entityKey)).ToArray();
            foreach (var item in entityFields)
            {
                businessInfo.Remove(item);
            }
            foreach (var fieldAppearance in dynamicLayoutInfo.GetFieldAppearances())
            {
                businessInfo.Add(fieldAppearance.Field);
            }
            // 修改了元数据，重新生成该元数据的类型定义
            businessInfo.GetDynamicObjectType(true);
            e.BusinessInfo = businessInfo;
            e.BillBusinessInfo = businessInfo;
        }
        /// <summary>
        /// 动态设置表单布局元数据
        /// </summary>
        /// <param name="e"></param>
        public override void OnSetLayoutInfo(SetLayoutInfoArgs e)
        {
            base.OnSetLayoutInfo(e);
            //动态创建LayoutInfo
            var layoutInfo = (LayoutInfo)ObjectUtils.CreateCopy(this.View.LayoutInfo);
            var entityFieldAps = layoutInfo.GetFieldAppearances().Where(o => o.EntityKey.EqualsIgnoreCase(entityKey)).ToArray();
            foreach (var item in entityFieldAps)
            {
                layoutInfo.Remove(item);
            }
            foreach (var fieldAppearance in dynamicLayoutInfo.GetFieldAppearances())
            {
                layoutInfo.Add(fieldAppearance);
            }
            e.LayoutInfo = layoutInfo;
            e.BillLayoutInfo = layoutInfo;
            // 给表格动态创建列
            var gridAP = layoutInfo.GetEntryEntityAppearance(entityKey);
            var entryGrid = this.View.GetControl<EntryGrid>(entityKey);
            entryGrid.CreateDyanmicList(gridAP);
        }
        /// <summary>
        /// 初始化当前动态表单的数据包
        /// </summary>
        /// <param name="e"></param>
        public override void BeforeBindData(EventArgs e)
        {
            base.BeforeBindData(e);
            this.Model.DataObject = new DynamicObject(this.View.BusinessInfo.GetDynamicObjectType());
        }
        /// <summary>
        /// 给动态表格绑定数据
        /// </summary>
        /// <param name="e"></param>
        public override void AfterBindData(EventArgs e)
        {
            base.AfterBindData(e);
            BindData();
        }
        public override void BarItemClick(BarItemClickEventArgs e)
        {
            base.BarItemClick(e);
            if (e.BarItemKey.EqualsIgnoreCase("tbRefresh"))
            {
                BindData();
                return;
            }
        }
        private void BindData()
        {
            var entryEntity = this.View.BusinessInfo.GetEntryEntity(entityKey);
            var entryEntityData = this.Model.GetEntityDataObject(entryEntity);
            entryEntityData.Clear();
            for (var x = 1; x < 21; ++x)
            {
                DynamicObject rowData = new DynamicObject(entryEntityData.DynamicCollectionItemPropertyType);
                if (entryEntity.SeqDynamicProperty != null)
                {
                    entryEntity.SeqDynamicProperty.SetValue(rowData, x);
                }
                foreach (var fieldName in fieldNames)
                {
                    rowData["F" + fieldName] = string.Format("{0}：{1}", fieldName, Guid.NewGuid());
                }
                entryEntityData.Add(rowData);
            }
            this.View.UpdateView(entityKey);
        }
        #endregion
    }
    #region 元数据操作辅助类
    /// <summary>
    /// 元数据操作辅助类
    /// </summary>
    public static class MetadataUtils
    {
        /// <summary>
        /// 创建字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <param name="ctx"></param>
        /// <param name="entityKey"></param>
        /// <param name="fieldName"></param>
        /// <param name="caption"></param>
        /// <param name="propName"></param>
        /// <param name="elementType"></param>
        /// <returns></returns>        
        public static T CreateField<T, K>(Context ctx, string entityKey, string fieldName, string caption, string propName = "", ElementType elementType = null)
            where T : FieldAppearance, new()
            where K : Field, new()
        {
            var fieldAppearance = new T();
            fieldAppearance.Field = new K();
            if (elementType != null)
            {
                PropertyUtil.SetAppearenceDefaultValue(fieldAppearance, elementType, ctx.UserLocale.LCID);
                PropertyUtil.SetBusinessDefaultValue(fieldAppearance.Field, elementType, ctx.UserLocale.LCID);
            }
            fieldAppearance.Key = fieldName;
            fieldAppearance.EntityKey = entityKey;
            fieldAppearance.Caption = new LocaleValue(caption, ctx.UserLocale.LCID);
            fieldAppearance.Width = new LocaleValue("300", ctx.UserLocale.LCID);
            fieldAppearance.Locked = -1;
            fieldAppearance.Visible = -1;
            //
            fieldAppearance.Field.Key = fieldName;
            fieldAppearance.Field.EntityKey = entityKey;
            fieldAppearance.Field.Name = fieldAppearance.Caption;
            fieldAppearance.Field.FieldName = fieldName;
            fieldAppearance.Field.PropertyName = string.IsNullOrWhiteSpace(propName) ? fieldName : propName;
            fieldAppearance.Field.FireUpdateEvent = 0;
            return fieldAppearance;
        }
        /// <summary>
        /// 创建字段
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="layoutInfo"></param>
        /// <param name="entityKey"></param>
        /// <param name="fields"></param>
        public static void CreateFields(Context ctx, LayoutInfo layoutInfo, string entityKey, string[] fields)
        {
            var dynamicObjectType = new DynamicObjectType("f_displayer");
            // 添加选择列
            var checkBoxFieldAp = CreateField<CheckBoxFieldAppearance, CheckBoxField>(ctx, entityKey, "F_MultiSelectKey", "选择");
            checkBoxFieldAp.Width = new LocaleValue("60", ctx.UserLocale.LCID);
            checkBoxFieldAp.Locked = 0;
            checkBoxFieldAp.Field.DefValue = "0";
            FieldRegisterDynamicProperty(checkBoxFieldAp.Field, dynamicObjectType);
            layoutInfo.Add(checkBoxFieldAp);
            // 添加其他列
            foreach (var colName in fields)
            {
                string key = string.Format("F{0}", colName);
                var fieldAp = CreateField<TextFieldAppearance, TextField>(ctx, entityKey, key, colName, key);
                FieldRegisterDynamicProperty(fieldAp.Field, dynamicObjectType);
                layoutInfo.Add(fieldAp);
            }
        }
        /// <summary>
        /// 给字段动态注册属性
        /// </summary>
        /// <param name="field"></param>
        /// <param name="dynamicObjectType"></param>
        private static void FieldRegisterDynamicProperty(Field field, DynamicObjectType dynamicObjectType)
        {
            var methodInfo = field.GetType().GetMethod("RegisterDynamicProperty", BindingFlags.Instance | BindingFlags.NonPublic);
            if (methodInfo == null)
            {
                return;
            }
            methodInfo.Invoke(field, new object[] { dynamicObjectType });
        }
    }
    #endregion
}
